Skip to content

Conversation

@Kivooeo
Copy link
Member

@Kivooeo Kivooeo commented Oct 29, 2025

Currently, there are blanket implementations for &F and &mut F for FnMut and FnOnce, but not for Fn, as a result, &mut F implements fewer of the Fn traits than &F, which is inconsistent and this PR fills that coherence hole

Technically, this is a breaking change because Fn is a fundamental trait, however, practical breakage is expected to be minimal, as such overlapping impl patterns are extremely rare

pub trait Trait {}
impl<F: Fn()> Trait for F {}
impl Trait for &fn() {}     // not allowed
impl Trait for &mut fn() {} // allowed

Because of this, second impl for &mut fn() works fine but shouldn't

Fixes #147931

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver) labels Oct 29, 2025
@rustbot
Copy link
Collaborator

rustbot commented Oct 29, 2025

r? @scottmcm

rustbot has assigned @scottmcm.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@Noratrieb Noratrieb added the needs-crater This change needs a crater run to check for possible breakage in the ecosystem. label Oct 29, 2025
@Noratrieb
Copy link
Member

@bors try

@rust-bors

This comment has been minimized.

rust-bors bot added a commit that referenced this pull request Oct 29, 2025
Add missing `impl Fn for &mut F where F: Fn`
@Noratrieb
Copy link
Member

r? libs-api

@rustbot rustbot added the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label Oct 29, 2025
@rustbot rustbot assigned the8472 and unassigned scottmcm Oct 29, 2025
@rust-bors
Copy link

rust-bors bot commented Oct 30, 2025

☀️ Try build successful (CI)
Build commit: ddcf048 (ddcf048784667508cd676fef4667f88ae15628a3, parent: 292be5c7c05138d753bbd4b30db7a3f1a5c914f7)

@theemathas theemathas added the needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. label Oct 30, 2025
@saethlin
Copy link
Member

@craterbot run mode=check-only

@craterbot
Copy link
Collaborator

👌 Experiment pr-148271 created and queued.
🤖 Automatically detected try build ddcf048
🔍 You can check out the queue and this experiment's details.

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-crater Status: Waiting on a crater run to be completed. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 30, 2025
@craterbot
Copy link
Collaborator

🚧 Experiment pr-148271 is now running

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot
Copy link
Collaborator

🎉 Experiment pr-148271 is completed!
📊 6 regressed and 4 fixed (726473 total)
📊 1786 spurious results on the retry-regessed-list.txt, consider a retry1 if this is a significant amount.
📰 Open the summary report.

⚠️ If you notice any spurious failure please add them to the denylist!
ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

Footnotes

  1. re-run the experiment with crates=https://crater-reports.s3.amazonaws.com/pr-148271/retry-regressed-list.txt

@craterbot craterbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-crater Status: Waiting on a crater run to be completed. labels Oct 31, 2025
@Noratrieb
Copy link
Member

@craterbot
Copy link
Collaborator

👌 Experiment pr-148271-1 created and queued.
🤖 Automatically detected try build ddcf048
🔍 You can check out the queue and this experiment's details.

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-crater Status: Waiting on a crater run to be completed. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 31, 2025
@craterbot
Copy link
Collaborator

🚧 Experiment pr-148271-1 is now running

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot
Copy link
Collaborator

🎉 Experiment pr-148271-1 is completed!
📊 1 regressed and 0 fixed (1777 total)
📊 102 spurious results on the retry-regessed-list.txt, consider a retry1 if this is a significant amount.
📰 Open the summary report.

⚠️ If you notice any spurious failure please add them to the denylist!
ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

Footnotes

  1. re-run the experiment with crates=https://crater-reports.s3.amazonaws.com/pr-148271-1/retry-regressed-list.txt

@craterbot craterbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-crater Status: Waiting on a crater run to be completed. labels Nov 5, 2025
@theemathas
Copy link
Contributor

The only non-spurious failure was from the currying crate. I've minimized the code from that crate to below:

#![feature(unboxed_closures)]
#![feature(fn_traits)]

#[allow(dead_code)]
pub struct Curried<F> {
    func: F,
}

impl<F: FnOnce()> FnOnce<()> for Curried<F> {
    type Output = ();
    extern "rust-call" fn call_once(self, _: ()) {}
}
impl<F: FnMut()> FnMut<()> for Curried<F> {
    extern "rust-call" fn call_mut(&mut self, _: ()) {}
}
impl<F: Fn()> Fn<()> for Curried<F> {
    extern "rust-call" fn call(&self, _: ()) {}
}

pub fn test_mut() {
    let mut i = 0;
    let mut f = || {
        i += 1;
    };
    let mut fj = Curried { func: &mut f };
    fj();
}

Error after this PR:

error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnMut`
  --> src\lib.rs:22:17
   |
22 |     let mut f = || {
   |                 ^^ this closure implements `FnMut`, not `Fn`
23 |         i += 1;
   |         - closure is `FnMut` because it mutates the variable `i` here
...
26 |     fj();
   |     ---- the requirement to implement `Fn` derives from here
   |
   = note: required for `&mut {closure@src\lib.rs:22:17: 22:19}` to implement `Fn()`
   = note: 1 redundant requirement hidden
   = note: required for `Curried<&mut {closure@src\lib.rs:22:17: 22:19}>` to implement `Fn()`

For more information about this error, try `rustc --explain E0525`.
error: could not compile `currying` (lib) due to 1 previous error

I don't understand why it's erroring though...

@BoxyUwU
Copy link
Member

BoxyUwU commented Nov 6, 2025

gonna nominate this for T-types. I am not sure to what extent we actually depend on the exact set of Fn* impls in core/std from within the compiler. It would seem plausible to me that method lookup or the trait solver could be making assumptions about the kind of impls that exist.

@BoxyUwU BoxyUwU added the I-types-nominated Nominated for discussion during a types team meeting. label Nov 6, 2025
@programmerjake
Copy link
Member

programmerjake commented Nov 6, 2025

can you add AsyncFn for &mut impl AsyncFn too?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

I-types-nominated Nominated for discussion during a types team meeting. needs-crater This change needs a crater run to check for possible breakage in the ecosystem. needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

&mut impl Fn() does not implement Fn()

10 participants